//清理脚本 by略游
//所有客户端都需要执行，这样才有函数的定义。然后只服务器执行循环

asc_center_pos = getArray(configFile >> "CfgWorlds" >> worldName >> "centerPosition");

if(Param_Debug == 1)then{
	asc_dis_blood = 0;
	asc_dis_easy = 0;
	asc_dis_paricle = 0;
	asc_dis_live_man = 2000;
	asc_dis_veh = 500;
	asc_dis_dead = 0;
	asc_dis_mine = 2000;
	asc_dis_ruins = 0;
}else{
	asc_dis_blood = 80;
	asc_dis_easy = 80;
	asc_dis_paricle = 80;
	asc_dis_live_man = 2000;
	asc_dis_veh = 1000;
	asc_dis_dead = 80;
	asc_dis_mine = 2000;
	asc_dis_ruins = 1000;
};

//-------------------------------------特定对象清理-------------------------------------
//清理血迹等特定veh（不一定是血迹）
asc_blood = [
	"BloodSplatter_01_Large_New_F",
	"BloodSplatter_01_Medium_New_F",
	"BloodSplatter_01_Small_New_F",
	"BloodSpray_01_New_F",
	"BloodPool_01_Large_New_F",
	"BloodPool_01_Medium_New_F",
	"BloodTrail_01_New_F",
	"UserTexture1m_F",
	"UserTexture_1x2_F"
];


fn_cleanup_blood = {
	private _num = 0;
	_allPlayers = allUnits select {isPlayer _x && {!(_x isKindOf "HeadlessClient_F")}};
	
	_BloodSplatter = nearestObjects [asc_center_pos, asc_blood, worldSize];
	
	{
		_Delete_this = _x;
		if ((({((_x distance _Delete_this) <= asc_dis_blood)} count _allPlayers) isEqualTo 0)) then 
		{		
			_num = _num + 1;
			deleteVehicle _x
		};
	} forEach _BloodSplatter;
	_num
};

//-------------------------------------简单对象清理-------------------------------------
asc_easy = [
	"BloodSplatter_01_Large_New_F",
	"BloodSplatter_01_Medium_New_F",
	"BloodSplatter_01_Small_New_F",
	"BloodSpray_01_New_F",
	"BloodPool_01_Large_New_F",
	"BloodPool_01_Medium_New_F",
	"BloodTrail_01_New_F",
	"UserTexture1m_F",
	"UserTexture_1x2_F"
];
	
fn_cleanup_easy = {
	private _num = 0;
	_allPlayers = allUnits select {isPlayer _x && {!(_x isKindOf "HeadlessClient_F")}};
	
	_BloodSplatter = allSimpleObjects asc_easy;
	
	{
		_Delete_this = _x;
		if ((({((_x distance _Delete_this) <= asc_dis_easy)} count _allPlayers) isEqualTo 0)) then 
		{		
			_num = _num + 1;
			deleteVehicle _x
		};
	} forEach _BloodSplatter;
	_num
};
	
//本地
fn_cleanup_local = {
	private _num = 0;
	{ deleteVehicle _x;_num = _num + 1} forEach (allMissionObjects "#slop");
	{ deleteVehicle _x;_num = _num + 1} forEach (allMissionObjects "#mark");
	{ deleteVehicle _x;_num = _num + 1} forEach (allMissionObjects "#track");
	{ deleteVehicle _x;_num = _num + 1} forEach (allMissionObjects "#crater");
	{ deleteVehicle _x;_num = _num + 1} forEach (allMissionObjects "#crateronvehicle");
	{ deleteVehicle _x;_num = _num + 1} forEach (allMissionObjects "#explosion");
	{ deleteVehicle _x;_num = _num + 1} forEach (allMissionObjects "#objectdestructed");
	{ deleteVehicle _x;_num = _num + 1} forEach (allMissionObjects "#soundonvehicle");
	{ deleteVehicle _x;_num = _num + 1} forEach (allMissionObjects "#dynamicsound");
	{ deleteVehicle _x;_num = _num + 1} forEach (allMissionObjects "#particlesource");
	
	//现在血迹都是简单对象，1.8版本不是
	if(Param_Version <= 183)then{
		_num = _num + (call fn_cleanup_blood);
	};
	
	
	_num = _num + (call fn_cleanup_easy);
	
	hint format["本地清理了: %1物体",_num];
};

//服务器
fn_cleanup_server = 
{
	private _num_unit = 0;
	private _num_dead = 0;
	private _num_veh = 0;
	private _num_mine = 0;
	private _num_item = 0;
	private _num_other = 0;
	private _num_group = 0;
	private _num_trigger = 0;
	
	//杀死所有清理单位（漏网之鱼）（在玩家一定范围外）1200
	{
		if((!isNull _x) && (alive _x) && (!isPlayer _x) && (!((group _x) getVariable["no_cleanup", false]))) then
		{
			private _unit = _x;
			private _clean = true;
			{
				if(_x distance _unit < asc_dis_live_man) exitWith
				{
					_clean = false;
				};
			}forEach AllPlayers;
			if(_clean) then
			{
				deleteVehicle _unit;// setDamage [1, false];
				_num_unit = _num_unit + 1;
			};
		};
	}forEach allUnits;

	//移除玩家范围外所有载具（并且速度小于100），标记载具不清理 500m，UAV没有连接到玩家
	{
		private _veh = _x;
		if (!(_veh getVariable["no_cleanup", false]) && {speed _veh < 100} && {!(isUAVConnected _veh)}) then
		{
			private _clean = true;
			{
				if(_x distance _veh < asc_dis_veh) exitWith
				{
					_clean = false;
				};
			}forEach AllPlayers;
			if(_clean) then
			{
				{
					deleteVehicle _x;//setDamage [1, false];
				}forEach (crew _veh);
				deleteVehicle _veh;
				_num_veh = _num_veh + 1;
			};		
		};
	} forEach ((allMissionObjects "Car") + (allMissionObjects "Tank") + (allMissionObjects "Ship") + (allMissionObjects "Air"));
	
	
	//移除没有单位的固定
	{
		private _veh = _x;
		if (!(_veh getVariable["no_cleanup", false])
			&& {count crew _veh != 0})then
		{
			private _clean = true;
			{
				if(_x distance _veh < asc_dis_veh) exitWith
				{
					_clean = false;
				};
			}forEach AllPlayers;
			if(_clean) then
			{
				{
					deleteVehicle _x;//setDamage [1, false];
				}forEach (crew _veh);
				deleteVehicle _veh;
				_num_veh = _num_veh + 1;
			};		
		};	
	} forEach (allMissionObjects "StaticWeapon");
	
	//消除死亡单位 80米以外（不是玩家）
	private _list_dead = allDead;
	_list_dead = _list_dead select{
		(!isPlayer _x)
	};
	{
		private _veh = _x;
		private _clean = true;
		{
			if(_x distance _veh < asc_dis_dead) exitWith
			{
				_clean = false;
			};
		}forEach AllPlayers;
		if(_clean) then
		{
			deleteVehicle _veh;
			_num_dead = _num_dead + 1;
		};		
	}forEach _list_dead;
	
	//移除地面物品
	{
		private _veh = _x;
		if(!(_veh getVariable["no_cleanup", false]))then{
			private _clean = true;
			{
				if(_x distance _veh < asc_dis_dead) exitWith
				{
					_clean = false;
				};
			}forEach AllPlayers;
			if(_clean) then
			{
				deleteVehicle _veh;
				_num_item = _num_item + 1;
			};
		};
	} forEach (allMissionObjects "WeaponHolder");
	
	//移除地雷
	{ 
		private _veh = _x;
		private _clean = true;
		{
			if(_x distance _veh < asc_dis_mine) exitWith
			{
				_clean = false;
			};
		}forEach AllPlayers;
		if(_clean) then
		{
			deleteVehicle _veh;
			_num_mine = _num_mine + 1;
		};		
	} forEach allMines;
	
	//移除弹坑
	{deleteVehicle _x;_num_other = _num_other + 1 } forEach ((allMissionObjects "Crater")+
		(allMissionObjects "CraterLong")+
		(allMissionObjects "CraterLong_small"));
		
	//移除废墟
	{
		private _veh = _x;
		private _clean = true;
		{
			if(_x distance _veh < asc_dis_ruins) exitWith
			{
				_clean = false;
			};
		}forEach AllPlayers;
		if(_clean) then
		{
			deleteVehicle _veh;
			_num_other = _num_other + 1;
		};
	} forEach (allMissionObjects "ruins");
	
	//空组
	{
		if (((count units _x) isEqualTo 0) 
		&& {_x != as_group_g}
		&& {_x != as_group_medic}) then 
		{
			deleteGroup _x; 
			_num_group = _num_group + 1
		};
	} count allGroups;
	
	//触发器
	{ 
		//if (!(_x getVariable["no_cleanup", false]))then{
			deleteVehicle _x;_num_trigger = _num_trigger + 1;
		//};
	} forEach (allMissionObjects "emptyDetector");
	
	format["服务器清理了: %1较远单位 %2尸体 %3载具 %4地面物品 %5较远的地雷 %6特殊效果 %7空单位组 %8脚本触发器", _num_unit, _num_dead, _num_veh, _num_item, _num_mine, _num_other, _num_group, _num_trigger] remoteExec ["hint"]; 

};

fn_cleanup_all =
{
	//先清理本地
	[] remoteExec ["fn_cleanup_local", 0]; 
	
	uiSleep 20;
	
	[] call fn_cleanup_server;
};


fn_cleanup_force =
{
	private _list = AllPlayers;
	if(!isNil "as_npc" && {alive as_npc})then{_list pushBack as_npc};
	if(!isNil "as_npc_red")then{_list pushBack as_npc_red};
	
	//非简单对象
	{
		//防止玩家双枪被清理
		if(typeOf _x != "GroundWeaponHolder_Scripted")then{
			private _clean = true;
			private _unit = _x;
			{
				if(_x distance _unit < 1200) exitWith
				{
					_clean = false;
				};
			}forEach _list;
			if(_clean) then{
				if(_x isKindOf "Man")then{
					//不是玩家并且没有名字（上校和中尉都有名字）
					if(!isPlayer _x && {(_x getVariable["as_name", ""]) == ""})then{ deleteVehicle _x;};
				}else{
					private _crew = crew _x;
					private _noPlayer = true;
					{
						//有玩家和红方乘员的不删除
						if(isPlayer _x || {side _x == east}) exitWith{_noPlayer = false;};
					}forEach _crew;

					if(_noPlayer)then{
						//根据箱子删除点标记
						if(typeOf _x == "CargoNet_01_box_F")then{
							deleteMarker (_x getVariable["marker_name", ""]);
						};
						
						private _veh = _x;
						{
							deleteVehicle _x;
						}forEach _crew;
						deleteVehicle _veh;
					};
				};
			};
		};
	}forEach ([worldSize / 2, worldSize / 2] nearObjects ["All",worldSize * 0.7]);
	
	//简单对象
	{
		private _clean = true;
		private _unit = _x;
		{
			if(_x distance _unit < 1200) exitWith
			{
				_clean = false;
			};
		}forEach _list;
		if(_clean) then{
			deleteVehicle _unit;
		};
	}forEach allSimpleObjects[];
};
 
if(isServer)then{
	
	[] spawn{
		while {true} do
		{
			waitUntil{uiSleep 60; diag_fps < 10};
			uiSleep 120;
			if(diag_fps < 13)then{
				"由于服务器帧数过低，即将清除远离玩家的物体" remoteExec ["hint"];
				uiSleep 10;	
				call fn_cleanup_force;
				Sleep 30;
			};
		};
	};
	
	
	while {true} do
	{
		uiSleep 300;//5分钟间隔最低
		//直到帧率过低
		waitUntil{Sleep 30;diag_fps < Param_MinFPS};
		"即将开始执行服务器清理操作" remoteExec ["hint"];
		uiSleep 10;
		[] spawn fn_cleanup_all;
	};
};

